package com.heima.article.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.heima.article.entity.ApArticle;
import com.heima.article.entity.ApArticleContent;
import com.heima.article.entity.ApAuthor;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.article.service.ApArticleContentService;
import com.heima.article.service.ApArticleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.article.service.ApAuthorService;
import com.heima.article.service.ArticleFreemarkerService;
import com.heima.common.enums.AppHttpCodeEnum;
import com.heima.common.exception.LeadException;
import com.heima.common.util.BeanHelper;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.article.dtos.ArticleHomeDto;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 文章信息表，存储已发布的文章 服务实现类
 * </p>
 *
 * @author HM
 * @since 2022-03-01
 */
@Slf4j
@Service
public class ApArticleServiceImpl extends ServiceImpl<ApArticleMapper, ApArticle> implements ApArticleService {
    @Autowired
    private ApAuthorService apAuthorService;
    @Autowired
    private ApArticleContentService apArticleContentService;

    @Autowired
    private ArticleFreemarkerService articleFreemarkerService;

    //保存文章
    @Override
    @Transactional(rollbackFor = Exception.class)//开启本地事务
    public Long saveArticle(ArticleDto dto) {
        //1. 根据自媒体文章id，查询文章信息
        LambdaQueryWrapper<ApArticle> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ApArticle::getWmNewsId, dto.getWmNewsId());
        ApArticle article = getOne(queryWrapper);
        if (article == null) {
            article = new ApArticle();
            article.setWmNewsId(dto.getWmNewsId());
            //1.1 根据自媒体文章作者id查询authorId
            ApAuthor apAuthor = apAuthorService.findByWmUserId(dto.getWmUserId());
            article.setAuthorId(apAuthor.getId());
            article.setAuthorName(apAuthor.getName());
            article.setCreatedTime(new Date());
            article.setIsDelete(false);
            article.setIsDown(false);
            article.setIsComment(true);
            article.setIsForward(true);
            article.setFlag(0);
        }
        article.setPublishTime(dto.getPublishTime() == null ? new Date() : dto.getPublishTime());
        article.setLabels(dto.getLabels());
        article.setImages(dto.getImages());
        article.setChannelId(dto.getChannelId());
        article.setChannelName(dto.getChannelName());
        article.setTitle(dto.getTitle());
        article.setLayout(dto.getLayout());
        //2. 保存/修改文章表
        boolean b = saveOrUpdate(article);
        if (!b) {
            log.error("保存文章失败");
            throw new LeadException(AppHttpCodeEnum.SERVER_ERROR);
        }
        //3. 获取文章id
        Long articleId = article.getId();

        ApArticleContent apArticleContent = new ApArticleContent();
        apArticleContent.setArticleId(articleId);
        apArticleContent.setContent(dto.getContent());
        apArticleContent.setContent(dto.getContent());
        //4. 保存/修改 文章内容表
        boolean b1 = apArticleContentService.saveOrUpdate(apArticleContent);
        if (!b1) {
            log.error("保存文章内容表失败");
            throw new LeadException(AppHttpCodeEnum.SERVER_ERROR);
        }
        log.info("返回文章id={}", articleId);

        //        异步调用 生成静态文件上传到minio中
        articleFreemarkerService.buildArticleToMinIO(article, dto.getContent());

        return articleId;
    }

    //单页加载最大的数字
    private final static short MAX_PAGE_SIZE = 10;

    //app首页显示文章数据
    @Override
    public List<ArticleDto> load(ArticleHomeDto dto, int type) {
        Integer size = dto.getSize();
        if (size == null || size == 0) {
            size = 10;
        }
        size = Math.min(size, MAX_PAGE_SIZE);
        IPage<ApArticle> iPage = new Page<>(1, size);
        LambdaQueryWrapper<ApArticle> queryWrapper = new LambdaQueryWrapper<>();
        //1. 判断是否传递了频道信息
        if (dto.getChannelId() != null && dto.getChannelId() != 0) {
            queryWrapper.eq(ApArticle::getChannelId, dto.getChannelId());
        }
        //2. 查询时间
        if (type == 1) {
            // 用户下拉，查询发布时间 大与 最大时间的文章
            queryWrapper.gt(ApArticle::getPublishTime, dto.getMaxTime());
        } else {
            // 用户上拉，查询发布时间小于最小时间的文章
            queryWrapper.lt(ApArticle::getPublishTime, dto.getMinTime());
        }
        //3. 查询到了发布时间，且未删除的，且按照时间排序的
        queryWrapper.eq(ApArticle::getIsDown, false).
                eq(ApArticle::getIsDelete, false).
                orderByDesc(ApArticle::getPublishTime);
        //4. 分页查询
        IPage<ApArticle> apArticleIPage = page(iPage, queryWrapper);
        if (apArticleIPage != null && !CollectionUtils.isEmpty(apArticleIPage.getRecords())) {
            List<ArticleDto> articleDtos = BeanHelper.copyWithCollection(apArticleIPage.getRecords(), ArticleDto.class);
            return articleDtos;
        }
        return Collections.emptyList();
    }

    //上下架
    @Override
    public void upOrDown(Map<String, Long> map) {
        LambdaUpdateWrapper<ApArticle> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(ApArticle::getId, map.get("articleId")).
                set(ApArticle::getIsDown, map.get("enable").intValue() == 1 ? false : true);
        boolean b = update(updateWrapper);
        if (!b) {
            throw new LeadException(AppHttpCodeEnum.SERVER_ERROR);
        }
    }


    //分页查询文章信息
    @Override
    public List<ArticleDto> findArticleByPage(Integer page, Integer size) {
        //设置分页
        IPage<ApArticle> iPage = new Page<>(page,size);
        //第一种方法
//        //设置条件
//        LambdaQueryWrapper<ApArticle> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.eq(ApArticle::getIsDelete,false).eq(ApArticle::getIsDown,false);
//        //分页查询
//        IPage<ApArticle> apArticleIPage = page(ipage,queryWrapper);
//        if (apArticleIPage==null||CollectionUtils.isEmpty(apArticleIPage.getRecords())){
//            return null;
//        }
//        //类型转换
//        List<ArticleDto> articleDtos = BeanHelper.copyWithCollection(apArticleIPage.getRecords(), ArticleDto.class);
//        return articleDtos;
        //第二种：查询文章表和文章详情表
        IPage<ArticleDto> apArticleIPage = this.getBaseMapper().selectArticleContentByPage(iPage);
        if(apArticleIPage == null || CollectionUtils.isEmpty(apArticleIPage.getRecords())){
            return null;
        }
        return apArticleIPage.getRecords();
    }
}